package cn.com.chengmandian.bike.controller;

import cn.com.chengmandian.agent.utils.AuthUtil;
import cn.com.chengmandian.agent.utils.ServletUtil;
import cn.com.chengmandian.bike.dto.MemberWalletChargeForm;
import cn.com.chengmandian.bike.log.ActionLog;
import cn.com.chengmandian.bike.model.*;
import cn.com.chengmandian.bike.service.*;
import cn.com.chengmandian.bike.utils.AliPayUtil;
import cn.com.chengmandian.bike.utils.WxPayUtil;
import cn.com.chengmandian.core.common.constants.CommonConstant;
import cn.com.chengmandian.core.redis.cache.AgentParamCacheService;
import cn.com.chengmandian.core.web.exceptions.BadResponseException;
import cn.com.chengmandian.core.web.pojo.AgentInfo;
import cn.com.chengmandian.core.web.pojo.AgentUser;
import cn.com.chengmandian.core.web.pojo.AjaxResult;
import cn.com.chengmandian.core.web.pojo.BikeParam;
import cn.com.chengmandian.core.web.utils.LocalMapUtil;
import cn.com.chengmandian.core.web.utils.SpringContextUtil;
import cn.com.chengmandian.service.bike.BikePayClient;
import cn.com.chengmandian.service.bike.constants.ChannelTypeEnum;
import cn.com.chengmandian.service.bike.constants.MemberPayBusinessTypeEnum;
import cn.com.chengmandian.service.bike.constants.PayChannelEnum;
import cn.com.chengmandian.service.bike.form.BikePayForm;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;

/**
 * <p>
 * 电单车运营-用户钱包 前端控制器
 * </p>
 *
 * @author AutoGenerator
 * @since 2021-12-11
 */
@Api(tags = "用户钱包相关接口")
@RestController
@RequestMapping("/member/wallet")
public class EbMemberWalletController {
    @Autowired
    private IEbMemberWalletService memberWalletService;

    @Autowired
    private IEbMemberPayService memberPayService;

    @Autowired
    private IEbMemberInfoService memberInfoService;

    @Autowired
    private AgentParamCacheService agentParamCacheService;

    @Autowired
    private IEbAgentInfoService agentInfoService;

    @Autowired
    private IEbPayAccountService payAccountService;

    @Autowired
    private BikePayClient payClient;

    @ApiOperation("用户充值")
    @PostMapping("/charge")
    @ActionLog(name="用户充值",description = "'参数：' + #memberWalletChargeForm")
    public AjaxResult charge(@RequestBody MemberWalletChargeForm memberWalletChargeForm) throws Exception {
        Assert.notNull(memberWalletChargeForm.getMoney(), "请填写充值金额");
        Assert.notNull(memberWalletChargeForm.getPayChannel(), "请选择充值渠道");
        Assert.isTrue(memberWalletChargeForm.getMoney().compareTo(new BigDecimal(0)) > 0, "充值金额必须大于0");
        EbMemberInfo memberInfo = memberInfoService.getById(AuthUtil.getAgentUser().getId());

        AgentInfo agentInfo = LocalMapUtil.getAgentInfo();
        Assert.notNull(agentInfo.getAreaId(), "缺少运营区");

        BikeParam bikeParam = agentParamCacheService.getParam(agentInfo.getId());
        if(bikeParam != null && !bikeParam.getUserRideAllowRecharge()) {
            throw new BadResponseException("平台暂时无法充值，如有疑问，可请联系客服！");
        }

        PayChannelEnum payChannel = PayChannelEnum.getByCode(memberWalletChargeForm.getPayChannel());
        Assert.notNull(payChannel, "支付渠道不合法");
        Assert.isTrue(payChannel.getCode().equals(PayChannelEnum.WXPAY.getCode()) || payChannel.getCode().equals(PayChannelEnum.ALIPAY.getCode()), "支付渠道不合法");

        EbAgentInfo info = agentInfoService.getById(agentInfo.getId());
        if (info.getPayAccountId() != null) {
            EbPayAccount payAccount = payAccountService.getPayAccount(info.getPayAccountId(), memberInfo.getId());
            if (payAccount != null) {
                BikePayForm form = new BikePayForm();
                form.setPayBusinessType(MemberPayBusinessTypeEnum.WALLET);
                form.setPayChannel(payChannel);
                form.setMoney(memberWalletChargeForm.getMoney());
                form.setOpenId(StrUtil.isNotBlank(memberWalletChargeForm.getOpenId()) ? memberWalletChargeForm.getOpenId() : memberInfo.getOpenId());
                form.setAlipayUserId(memberInfo.getAlipayUserId());
                form.setAlipayOpenId(memberInfo.getAlipayOpenId());
                form.setAreaId(agentInfo.getAreaId());
                form.setMemberId(AuthUtil.getAgentUser().getId());
                form.setClientIp(ServletUtil.getIp());
                return payClient.pay(agentInfo.getId(), form);
            }
        }

        EbMemberPay memberPay = memberPayService.createPay(agentInfo.getAreaId(), AuthUtil.getAgentUser().getId(), MemberPayBusinessTypeEnum.WALLET, null,
                memberWalletChargeForm.getMoney(), memberWalletChargeForm.getPayChannel());

        String notifyUrl = "http://"+ agentInfo.getDomain() + "/api/v1/bikeuser/notify";

        if (memberWalletChargeForm.getPayChannel().equals(PayChannelEnum.WXPAY.getCode())) {
            Assert.isTrue(StrUtil.isNotBlank(agentInfo.getWxMchId()), "未开启微信支付");
            if (memberWalletChargeForm.getChannelType().equals(ChannelTypeEnum.MINI.getCode())) {
                String openId = StrUtil.isNotBlank(memberWalletChargeForm.getOpenId()) ? memberWalletChargeForm.getOpenId() : memberInfo.getOpenId();
                Assert.isTrue(StrUtil.isNotBlank(openId), "缺少openid");
                return AjaxResult.success(WxPayUtil.jsapiTransactions(
                        agentInfo.getWxMiniAppid(),
                        agentInfo.getWxMchId(),
                        openId,
                        "用户钱包充值",
                        memberPay.getPayNo(),
                        memberPay.getMoney(),
                        agentInfo.getWxKeyPath(),
                        agentInfo.getWxCertPath(),
                        notifyUrl + "/wxpay/pay/" + LocalMapUtil.getAgentInfo().getAgentNo()
                ));
            }
        } else if (memberWalletChargeForm.getPayChannel().equals(PayChannelEnum.ALIPAY.getCode())) {
            if (memberWalletChargeForm.getChannelType().equals(ChannelTypeEnum.MINI.getCode())) {
                // 支付宝用户唯一标识user_id 和open_id必须有一个有值
                Assert.isTrue(StrUtil.isNotBlank(memberInfo.getAlipayUserId()) || StrUtil.isNotBlank(memberInfo.getAlipayOpenId()), "用户缺少支付宝用户标识");
                return AjaxResult.success(AliPayUtil.getTradeCreateRequestParam(
                        agentInfo.getAliMiniAppid(),
                        memberInfo.getAlipayUserId(),
                        memberInfo.getAlipayOpenId(),
                        "用户钱包充值",
                        memberPay.getPayNo(),
                        memberPay.getMoney(),
                        agentInfo.getAliPayPrivateKey(),
                        agentInfo.getAliPayCertPath(),
                        agentInfo.getAliPayPublicCertPath(),
                        agentInfo.getAliPayRootCertPath(),
                        notifyUrl + "/ali/pay/" + LocalMapUtil.getAgentInfo().getAgentNo()
                ));
            }
        }
        return AjaxResult.error("不支持的支付方式");
    }

    @ApiOperation("用户钱包信息")
    @GetMapping("/detail")
    public AjaxResult<EbMemberWallet> detail() {
        AgentUser agentUser = AuthUtil.getAgentUser();
        return AjaxResult.success(memberWalletService.getMemberWallet(agentUser.getId()));
    }
}
